package ying.sms;

import java.time.LocalDate;
import java.util.*;

/**
 * ClassName: StudentManagementSystem
 * Package: sms
 * Description:
 *
 * @Author 刘英杰
 * @Create 2024/5/17 19:12
 * @Version 1.0
 */

/*
利用Collection重构学生信息管理系统,重构以下功能

        - 添加学生
        - 添加的学生必须具备邮箱并且符合邮箱格式
        - 显示系统中所有的学生
        - 判断某个学生在系统中是否存在(根据学生姓名判断)
        - 根据学生学号查找某个学生
        - 求学生的平均成绩
        - 根据指定的入学日期获取该入学日期之前入学的学生
        - 根据指定的入学日期获取该入学日期之后入学的学生
*/


public class StudentManagementSystem03 {


    private ArrayList<Student> students = new ArrayList<>();


    /**
     * 统计某一科目下各种成绩的学生人数
     * @param subject 科目
     * @return  某一科目下各种成绩的学生HashMap
     */
    public HashMap<Integer,Integer> getScoreStatisticsBySubject(String subject)
    {
        HashMap<Integer, Integer> scoreStatistics = new HashMap<>();
        try {
            for (Student student : students) {
                int score = getScoreBySubjects(student,subject);
                if (scoreStatistics.containsKey(score))
                    scoreStatistics.put(score,scoreStatistics.get(score) + 1);
                else
                    scoreStatistics.put(score,1);
            }
        } catch (NullPointerException e) {
            System.out.println("处理学生成绩出错：" + e.getMessage());
            e.printStackTrace();
        }
        return scoreStatistics;
    }


    /**
     * 1.获取指定科目最高成绩的学生信息
     * 2.获取指定科目最低成绩的学生信息
     * 3.统计某一科目下各种成绩的学生人数
     */

    /**
     *
     * @param subjects  科目
     * @return  1.获取指定科目最高成绩的学生信息
     */
    public Student getStudentByHighestScore(String subjects){
        try {
            return Collections.max(students, new Comparator<Student>() {
                 @Override
                 public int compare(Student o1, Student o2) {
                     return getScoreBySubjects(o1,subjects) - getScoreBySubjects(o2,subjects);
                 }
             });
        } catch (NoSuchElementException e) {
            System.out.println("没有找到任何学生:" + e.getMessage());
            e.printStackTrace();
            return null; //执行catch里面说明出问题,直接返回null;
        }catch (ClassCastException e){
            System.out.println("学生的分数不可比较:" + e.getMessage());
            e.printStackTrace();
            return null;//执行catch里面说明出问题,直接返回null;
        }
    }

    /**
     *
     * @param subjects 科目
     * @return  2.获取指定科目最低成绩的学生信息
     */
    public Student getStudentByLowestScore(String subjects){
        try {
            return Collections.min(students, new Comparator<Student>() {
                @Override
                public int compare(Student o1, Student o2) {
                    return getScoreBySubjects(o1,subjects) - getScoreBySubjects(o2,subjects);
                }
            });
        }catch (NoSuchElementException e) {
            System.out.println("没有找到任何学生:" + e.getMessage());
            e.printStackTrace();
            return null; //执行catch里面说明出问题,直接返回null;
        }catch (ClassCastException e){
            System.out.println("学生的分数不可比较:" + e.getMessage());
            e.printStackTrace();
            return null;//执行catch里面说明出问题,直接返回null;
        }
    }


    public void SortByTotalScore(){
//        TreeSet<Student> tmp = new TreeSet<>(new Comparator<Student>() {
//            @Override
//            public int compare(Student o1, Student o2) {
//                int scoreResult = o2.getTotolScore() - o1.getTotolScore();
//                if (scoreResult == 0)
//                {
//                    int nameResult = o2.getName().compareTo(o2.getName());
//                    if (nameResult == 0)
//                    {
//                        return o2.getId() - o1.getId();
//                    }
//                    else return nameResult;
//                }
//                else return scoreResult;
//            }
//        });
//
//        tmp.addAll(students);
//        students.clear();
//        students.addAll(tmp);

        try {
            students.sort(new Comparator<Student>() {
                @Override
                public int compare(Student o1, Student o2) {
                    return o2.getTotolScore() - o1.getTotolScore();
                }
            });
        } catch (Exception e) {
            System.out.println("排序过程中出错：" + e.getMessage());
            e.printStackTrace();
        }

    }

    /**
     *
     * @return 随机取的学生
     */
    public Student randomRollCall()
    {
        try {
            return students.get(new Random().nextInt(students.size()));
        } catch (Exception e) {
            System.out.println("随机点名出错：" + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    /**
     *      根据序号更新学生信息的方法
     * @param idx 学生的编号
     * @param student 学生的新的信息(学生对象中封装新的信息)
     * @return  更改前的学生对象
     */
    public Student updateStudentByIndex(int idx, Student student)
    {
        try {
            if (idx >= 1 && idx <= students.size())
                return students.set(idx - 1,student);
            else{
    //            System.out.println("不存在序号为:" + idx + "的学生信息");
    //            return null;
                throw new RuntimeException("指定的学生序号超出范围: " + idx);
            }
        } catch (Exception e) {
            System.out.println("更新学生信息时出错:" + e.getMessage());
            e.printStackTrace();
            return  null;
        }
    }


    public boolean validateStudentEmai(Student student)
    {
        if (student == null || student.getEmal() == null) return false;
        else
        {
            return student.getEmal().matches("\\w+@\\w+\\.+\\w+");
        }
    }


    /**
     * 向指定容器中加学生
     * @param
     * @param student
     */
    public void addStudent(Student student)
    {
        try {
            if (student != null && validateStudentEmai(student))
            {
                students.add(student);
            }
        } catch (Exception e) {
            System.out.println("添加学生时出错：" + e.getMessage());
            e.printStackTrace();
        }
    }



    public void showAllStudent(Collection<Student> students)
    {
        try {
            int i = 1;
            for (Student student : students)
            {
                    System.out.println((i ++) + " " + student);
            }
        } catch (Exception e) {
            System.out.println("显示学生信息出错：" + e.getMessage());
            e.printStackTrace();
        }
    }

    public void showAllStudent()
    {
        showAllStudent(students);
    }


    public boolean is_contains(Student stu)
    {
//        if (stu == null) return false;
//
//        for (Object student : students)
//            if (student.equals(stu))
//                return true;
//
//        return false;
        try {
            return students.contains(stu);
        } catch (Exception e) {
            throw new RuntimeException(e);//将异常对象进一步封装,将来可以打印出e的信息
        }
    }


    public Student findStudentById(int id)
    {
        try {
            for (Student student : students)
            {
                if (student.getId() == id)
                    return student;
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return null;//说明该学号的学生不存在
    }

    public int getAverageScore(String subject)
    {
        try {
            int sum = 0;
            for (Student student : students)
            {
                int score = getScoreBySubjects(student, subject);
                sum += score;

            }
            return students.size() == 0 ? 0 : sum / students.size();
        } catch (Exception e) {
            throw new RuntimeException("计算平均分时出错：" + e);
        }
    }

    private int getScoreBySubjects(Student student, String subjects) { // ----------------------难点！！！
        try {
            switch(subjects)
            {
                case "语文" ->{
                    return student.getChineseScore();
                }
                case "数学" ->{
                    return student.getMathScore();
                }
                case "历史" ->{
                    if (student instanceof MiddleStudents middleStudents)
                        return middleStudents.getHistoryScore();
                }
                case "物理" ->{
                    if (student instanceof MiddleStudents middleStudents)
                        return middleStudents.getPhysicsScore();
                }
            }
            return 0;
        } catch (Exception e) {
            throw new RuntimeException("获取当前学生:" + student + "的" + subjects + "时出错", e);
        }
    }

    public Collection<Student> getStudentBeforeDate(String date)
    {
        Collection<Student> tmps = new ArrayList<>();
        try {
            for (Student student : students) {
    //            if (student != null && student.getEnrollmentDates() != null &&
    //                    student.getEnrollmentDates().isBefore(LocalDate.parse(date)) ||
    //                    student.getEnrollmentDates().isEqual(LocalDate.parse(date))) //LocalDate.parse(date)
    //                                                                                    //不指定模式就按照默认年-月-日
    //                addStudent(tmps,student);
                if (student.getEnrollmentDates() != null) {
                    if (student.getEnrollmentDates().isBefore(LocalDate.parse(date)) ||
                            student.getEnrollmentDates().isEqual(LocalDate.parse(date)))
    //                    addStudent(tmps, stu);
                        tmps.add(student);
                }

            }
        } catch (Exception e) {
            throw new RuntimeException("获取指定入学日期值之前入学的学生出错:", e);
        }
        return tmps;
    }

    public Collection<Student> getStudentAfterDate(String date)
    {
        Collection tmps = new ArrayList();
        try {
            for (Student student : students) {
    //            if (student != null && student.getEnrollmentDates() != null &&
    //                    student.getEnrollmentDates().isBefore(LocalDate.parse(date)) ||
    //                    student.getEnrollmentDates().isEqual(LocalDate.parse(date))) //LocalDate.parse(date)
    //                                                                                    //不指定模式就按照默认年-月-日
    //                addStudent(tmps,student);
                if (student.getEnrollmentDates() != null) {
                    if (student.getEnrollmentDates().isAfter(LocalDate.parse(date)) ||
                            student.getEnrollmentDates().isEqual(LocalDate.parse(date)))
    //                    addStudent(tmps, stu);
                        tmps.add(student);
                }

            }
        } catch (Exception e) {
            throw new RuntimeException("获取指定入学日期值之后入学的学生出错:", e);
        }
        return tmps;
    }

}
